package com.example.timingapplication

import android.annotation.SuppressLint
import android.os.Bundle
import android.util.Log
import android.widget.EditText
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatButton
import androidx.lifecycle.Observer
import androidx.work.Constraints
import androidx.work.ExistingWorkPolicy
import androidx.work.NetworkType
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkInfo
import androidx.work.WorkManager
import com.example.timingapplication.workers.DingTalkWorker
import com.example.timingapplication.workers.RedBookWorker
import java.util.Calendar
import java.util.concurrent.TimeUnit

class MainActivity : AppCompatActivity() {
    companion object {
        const val MORNING_WORK_TAG = "morning_dingtalk_work"
        const val NOON_WORK_TAG = "noon_redbook_work"
        const val EVENING_WORK_TAG = "evening_dingtalk_work"
    }

    private var etMorningWorkTime: EditText? = null
    private var etNoonWorkTime: EditText? = null
    private var etEveningWorkTime: EditText? = null
    private var btnWorkSetting: AppCompatButton? = null
    private lateinit var settingsManager: SettingsManager

    @SuppressLint("MissingInflatedId")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        etMorningWorkTime = findViewById(R.id.et_morning_work_time)
        etNoonWorkTime = findViewById(R.id.et_noon_work_time)
        etEveningWorkTime = findViewById(R.id.et_evening_work_time)
        btnWorkSetting = findViewById(R.id.btn_work_setting)
        
        // 初始化设置管理器
        settingsManager = SettingsManager.getInstance(this)
        
        /**
         *开始定时任务 使用WorkManager
         * 1.创建定时任务
         * 2.启动定时任务 循环每天 早上9点启动钉钉  晚上10点启动钉钉
         * 3.停止定时任务
         * 4.销毁定时任务
         */
        setupPeriodicWork()
        
        // 监听工作状态变化
        observeWorkStatus()
        
        btnWorkSetting?.setOnClickListener {
            val morningWorkTime = etMorningWorkTime?.text.toString().trim()
            val noonWorkTime = etNoonWorkTime?.text.toString().trim()
            val eveningWorkTime = etEveningWorkTime?.text.toString().trim()
            
            if (morningWorkTime.isEmpty() && noonWorkTime.isEmpty() && eveningWorkTime.isEmpty()) {
                Toast.makeText(this, "请至少填写一个时间", Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            }

            var hasError = false
            
            if (morningWorkTime.isNotEmpty()) {
                val morningTime = StringUtils.parseAndOptimizeTime(morningWorkTime)
                if (morningTime != null) {
                    Log.i("MainActivity", "morningTime: ${StringUtils.formatTime(morningTime[0], morningTime[1])}")
                    settingsManager.setMorningHour(morningTime[0])
                    settingsManager.setMorningMinute(morningTime[1])
                } else {
                    Toast.makeText(this, "早晨时间格式不正确", Toast.LENGTH_SHORT).show()
                    hasError = true
                }
            }
            
            if (noonWorkTime.isNotEmpty()) {
                val noonTime = StringUtils.parseAndOptimizeTime(noonWorkTime)
                if (noonTime != null) {
                    Log.i("MainActivity", "noonTime: ${StringUtils.formatTime(noonTime[0], noonTime[1])}")
                    settingsManager.setNoonHour(noonTime[0])
                    settingsManager.setNoonMinute(noonTime[1])
                } else {
                    Toast.makeText(this, "中午时间格式不正确", Toast.LENGTH_SHORT).show()
                    hasError = true
                }
            }
            
            if (eveningWorkTime.isNotEmpty()) {
                val eveningTime = StringUtils.parseAndOptimizeTime(eveningWorkTime)
                if (eveningTime != null) {
                    Log.i("MainActivity", "eveningTime: ${StringUtils.formatTime(eveningTime[0], eveningTime[1])}")
                    settingsManager.setEveningHour(eveningTime[0])
                    settingsManager.setEveningMinute(eveningTime[1])
                } else {
                    Toast.makeText(this, "晚上时间格式不正确", Toast.LENGTH_SHORT).show()
                    hasError = true
                }
            }
            
            // 如果有错误则不执行后续操作
            if (hasError) {
                return@setOnClickListener
            }
            
            stopPeriodicWork()
            setupPeriodicWork()
            Toast.makeText(this, "定时任务设置成功", Toast.LENGTH_SHORT).show()
        }
    }

    /**
     * 监听工作状态变化
     */
    private fun observeWorkStatus() {
        // 监听早晨任务状态
        WorkManager.getInstance(this).getWorkInfosByTagLiveData(MORNING_WORK_TAG)
            .observe(this, Observer { workInfos ->
                workInfos.forEach { workInfo ->
                    handleWorkInfo(MORNING_WORK_TAG, workInfo)
                }
            })

        // 监听中午任务状态
        WorkManager.getInstance(this).getWorkInfosByTagLiveData(NOON_WORK_TAG)
            .observe(this, Observer { workInfos ->
                workInfos.forEach { workInfo ->
                    handleWorkInfo(NOON_WORK_TAG, workInfo)
                }
            })

        // 监听晚上任务状态
        WorkManager.getInstance(this).getWorkInfosByTagLiveData(EVENING_WORK_TAG)
            .observe(this, Observer { workInfos ->
                workInfos.forEach { workInfo ->
                    handleWorkInfo(EVENING_WORK_TAG, workInfo)
                }
            })
    }

    /**
     * 处理工作状态信息
     */
    private fun handleWorkInfo(tag: String, workInfo: WorkInfo) {
        when (workInfo.state) {
            WorkInfo.State.ENQUEUED -> {
                Log.d("WorkStatus", "$tag 任务已加入队列")
            }
            WorkInfo.State.RUNNING -> {
                Log.d("WorkStatus", "$tag 任务正在运行")
            }
            WorkInfo.State.SUCCEEDED -> {
                Log.d("WorkStatus", "$tag 任务执行成功")
                Toast.makeText(this, "$tag 任务执行成功", Toast.LENGTH_SHORT).show()
            }
            WorkInfo.State.FAILED -> {
                Log.e("WorkStatus", "$tag 任务执行失败")
                Toast.makeText(this, "$tag 任务执行失败", Toast.LENGTH_SHORT).show()
            }
            WorkInfo.State.BLOCKED -> {
                Log.w("WorkStatus", "$tag 任务被阻塞")
            }
            WorkInfo.State.CANCELLED -> {
                Log.d("WorkStatus", "$tag 任务已取消")
            }
        }
    }

    /**
     * 设置定时任务
     * 创建并启动每天早上9点、中午12点和晚上10点的定时任务
     */
    private fun setupPeriodicWork() {
        // 定义工作约束条件（可选）
        val constraints = Constraints.Builder()
            .setRequiredNetworkType(NetworkType.NOT_REQUIRED)
            .build()

        // 从设置管理器获取时间设置，默认值为原来的固定时间
        val morningHour = settingsManager.getMorningHour(9)
        val morningMinute = settingsManager.getMorningMinute(0)
        val noonHour = settingsManager.getNoonHour(12)
        val noonMinute = settingsManager.getNoonMinute(0)
        val eveningHour = settingsManager.getEveningHour(22)
        val eveningMinute = settingsManager.getEveningMinute(0)

        // 计算到明天早上设置时间的延迟时间
        val morningDelay = calculateDelayToNextOccurrence(morningHour, morningMinute)
        // 计算到今天中午设置时间的延迟时间
        val noonDelay = calculateDelayToNextOccurrence(noonHour, noonMinute)
        // 计算到今天晚上设置时间的延迟时间
        val eveningDelay = calculateDelayToNextOccurrence(eveningHour, eveningMinute)

        // 创建早上工作请求
        val morningWork = OneTimeWorkRequestBuilder<DingTalkWorker>()
            .setInitialDelay(morningDelay, TimeUnit.MILLISECONDS)
            .setConstraints(constraints)
            .addTag(MORNING_WORK_TAG)
            .build()

        // 创建中午工作请求
        val noonWork = OneTimeWorkRequestBuilder<RedBookWorker>()
            .setInitialDelay(noonDelay, TimeUnit.MILLISECONDS)
            .setConstraints(constraints)
            .addTag(NOON_WORK_TAG)
            .build()

        // 创建晚上工作请求
        val eveningWork = OneTimeWorkRequestBuilder<DingTalkWorker>()
            .setInitialDelay(eveningDelay, TimeUnit.MILLISECONDS)
            .setConstraints(constraints)
            .addTag(EVENING_WORK_TAG)
            .build()

        // 启动定时任务
        WorkManager.getInstance(this).enqueueUniqueWork(
            MORNING_WORK_TAG,
            ExistingWorkPolicy.KEEP,
            morningWork
        )

        WorkManager.getInstance(this).enqueueUniqueWork(
            NOON_WORK_TAG,
            ExistingWorkPolicy.KEEP,
            noonWork
        )

        WorkManager.getInstance(this).enqueueUniqueWork(
            EVENING_WORK_TAG,
            ExistingWorkPolicy.KEEP,
            eveningWork
        )
        
        Log.d("WorkStatus", "定时任务已设置")
    }

    /**
     * 计算到下一个指定时间点的延迟（毫秒）
     * @param hourOfDay 小时 (24小时制)
     * @param minute 分钟
     * @return 到下一个指定时间点的延迟毫秒数
     */
    private fun calculateDelayToNextOccurrence(hourOfDay: Int, minute: Int): Long {
        val now = Calendar.getInstance()
        val nextOccurrence = Calendar.getInstance().apply {
            set(Calendar.HOUR_OF_DAY, hourOfDay)
            set(Calendar.MINUTE, minute)
            set(Calendar.SECOND, 0)
            set(Calendar.MILLISECOND, 0)

            // 如果当前时间已超过指定时间，则推迟到明天
            if (after(now)) {
                // 今天的时间点还未到，使用今天的
            } else {
                // 已经过了今天的时间点，推迟到明天
                add(Calendar.DAY_OF_MONTH, 1)
            }
        }

        return nextOccurrence.timeInMillis - now.timeInMillis
    }

    /**
     * 停止定时任务
     */
    private fun stopPeriodicWork() {
        WorkManager.getInstance(this).cancelUniqueWork(MORNING_WORK_TAG)
        WorkManager.getInstance(this).cancelUniqueWork(NOON_WORK_TAG)
        WorkManager.getInstance(this).cancelUniqueWork(EVENING_WORK_TAG)
    }

    /**
     * 销毁定时任务
     */
    private fun destroyPeriodicWork() {
        WorkManager.getInstance(this).cancelAllWork()
    }
}
